iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0

在現代應用程式中,非同步 API 不僅提升了系統的效率,還使得應用更加靈活且具備更高的可擴展性。非同步 API 的應用場景廣泛,從即時通知系統到雙向通訊,再到資料流的持續更新,都離不開良好的非同步設計。今天,我們將深入探討幾個常見的非同步 API 標準,並從設計角度討論如何納入關鍵考量,以確保系統的可靠性與可擴展性。


1. Webhook 傳送通知

Webhook 是一種常見的非同步通知機制,當特定事件發生時,服務端自動向指定的 URL 發送 HTTP 請求。它是一種「被動」的非同步操作,服務端不需要持續輪詢,而是等待事件發生後推送。

使用場景

  • 付款成功後通知第三方系統。
  • 用戶創建後通知 CRM 系統。
  • 監控系統發現異常時,通知相關人員或工具。

範例

POST /webhook/notify HTTP/1.1
Host: example.com
Content-Type: application/json

{
  "event": "order_created",
  "data": {
    "orderId": "123456",
    "userId": "78910",
    "amount": 250.00
  }
}

Webhook 通常簡單而直接,但要注意需要確保消息的可靠性,例如重試機制、簽名驗證等。


2. 用 SSE (Server-Sent Events) 推送訊息

SSE (Server-Sent Events) 是一種單向的非同步訊息傳遞方式,允許伺服器持續向客戶端發送訊息。這種方式適合那些需要頻繁更新的應用,如即時股價更新或新聞推送。

使用場景

  • 即時新聞推送。
  • 資料流監控,例如系統運行情況。
  • 用戶活動的持續跟蹤。

範例

GET /events HTTP/1.1
Host: example.com
Accept: text/event-stream

伺服器端會定期推送訊息,類似以下格式:

data: {"event": "price_update", "price": 125.30}
data: {"event": "stock_change", "stock": "AAPL"}

這種方式的優點是建立連線後,伺服器可以不斷推送事件,而不需要客戶端頻繁發起請求。


3. 用 WebSocket 進行雙向通知

WebSocket 是一種雙向的通信協議,允許客戶端和伺服器之間建立長連接,並能夠在連接期間自由地發送和接收訊息。這使得 WebSocket 非常適合需要雙向通信的應用。

使用場景

  • 即時聊天應用。
  • 在線遊戲中的即時通訊。
  • 需要雙向通訊的協作平台(如 Google Docs)。

範例

const socket = new WebSocket('wss://example.com/socket');

socket.onopen = function (event) {
    console.log("WebSocket is open now.");
};

socket.onmessage = function (event) {
    console.log("Received message: " + event.data);
};

socket.send("Hello Server!");

WebSocket 支持低延遲和高效的雙向通訊,非常適合需要即時交互的應用程序。


如何選擇合適的非同步 API 標準?

  1. Webhook:如果應用只需要單向事件通知,且對即時性要求不高,Webhook 是最簡單且有效的選擇。它的實現相對簡單,適合處理事件驅動的操作。
    • 適合:支付通知、訂單狀態更新等。
  2. SSE:如果應用需要持續的數據推送,但不需要雙向交互,SSE 提供了輕量級且易於實現的方案。特別適合即時數據流的場景。
    • 適合:即時新聞、監控數據等。
  3. WebSocket:當應用需要雙向通訊,並且需要即時性較高的互動,WebSocket 是首選。它可以滿足高頻次、高互動的場景需求。
    • 適合:即時聊天、即時遊戲等。

非同步 API 設計的核心考量

在設計非同步 API 時,有幾個重要的設計模式與策略應該考慮,這不僅有助於提升系統的靈活性與可靠性,還能確保系統在高併發場景下運行穩定。

1. 命令訊息

命令訊息是指用戶或系統向 API 發送的指令,要求伺服器執行某個具體操作(如創建訂單、修改數據)。這種訊息通常是同步的,但是可以設計成非同步處理,這樣伺服器可以快速返回,並在後台執行操作。

設計要點

  • API 返回一個立即的確認消息(如 202 Accepted),但實際處理在後台進行。
  • 可以提供一個狀態查詢的端點,讓用戶檢查命令的處理進度。

範例

POST /api/order
{
  "productId": "123",
  "quantity": 1
}

Response:
HTTP/1.1 202 Accepted
{
  "orderId": "78910",
  "status": "Processing"
}

2. 事件通知

事件通知是伺服器在某個操作完成後,主動向客戶端推送訊息的機制。這是非同步 API 中非常常見的設計模式。可以通過 Webhook、SSE 或 WebSocket 等多種技術實現。

設計要點

  • 提供一個配置通知端點的機制(例如客戶端可以提供回調 URL)。
  • 設計重試機制,確保通知能夠在傳輸失敗時重新發送。
  • 支持多種通知方式(例如 Webhook 和 SSE)。

範例

POST /webhook/notify
{
  "event": "order_completed",
  "data": {
    "orderId": "78910",
    "status": "Completed"
  }
}


3. 帶有狀態變更的事件

狀態變更事件是指當系統中的某個資源狀態發生變化時,系統向客戶端發送通知。例如,訂單狀態從「已處理」變為「已完成」時,系統可以通知客戶端。

設計要點

  • 設計一個狀態查詢 API,允許客戶端在接收到狀態變更事件後查詢具體的狀態細節。
  • 考慮如何處理多個狀態變更事件的順序問題,避免狀態錯誤。

範例

data: {"event": "order_status_updated", "orderId": "123", "status": "Shipped"}

這裡的 API 可以通知客戶端每次狀態變更,並且客戶端可以根據狀態來更新界面或進行後續操作。


4. 批次事件

有些情況下,事件會以批次的方式進行處理,這樣可以提高系統的吞吐量。批次事件設計常用於需要處理大量資料變更或持續不斷的事件流的情境中。

設計要點

  • 設計批次處理的 API,允許系統以一個批次的形式處理多個請求。
  • 考慮到 API 的響應時間,可以透過非同步處理和狀態查詢來減輕單次請求的負擔。

範例

data: [
  {"event": "price_updated", "productId": "123", "newPrice": 120.00},
  {"event": "price_updated", "productId": "456", "newPrice": 130.00}
]


5. 事件的排序

在非同步 API 設計中,事件的順序問題非常重要,特別是在處理狀態變更或批次事件時,事件的順序會直接影響到資料的正確性。

設計要點

  • 確保事件按正確的順序被處理(例如透過唯一的順序號或時間戳)。
  • 考慮如何處理亂序事件,設計回滾或重試機制。

範例

data: [
  {"event": "order_status_updated", "orderId": "123", "status": "Processing", "timestamp": "2024-01-01T12:00:00Z"},
  {"event": "order_status_updated", "orderId": "123", "status": "Shipped", "timestamp": "2024-01-01T12:05:00Z"}
]

這個設計確保事件按時間順序發送和處理,避免狀態錯亂。


結論與每日小結

非同步 API 設計不僅提升了系統的性能和反應速度,更使得應用具備了更強的可擴展性與靈活性。在這篇文章中,我們探討了幾種常見的非同步 API 標準,包括 Webhook、SSE 和 WebSocket,並介紹了非同步 API 設計時需要納入的考量,包括命令訊息、事件通知、狀態變更、批次事件與事件排序。

設計一個高效的非同步 API,必須要有全面的考量,從通知的機制到事件的處理方式,從資料的一致性到高併發處理,每一個細節都至關重要。


上一篇
Day 11: 非同步程式設計的挑戰與解決方案
系列文
使用 C# 從零開始玩轉 Web API,從基礎到微服務與雲端部署的全面探索12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言